<template>
  <div class="app-container">
    <!-- 搜索条件 -->
    <el-form :inline="true" class="mb-4">
      <el-form-item label="卖家昵称">
        <el-input
          v-model="queryParams.seller_name"
          placeholder="请输入卖家昵称"
          clearable
          style="width: 200px"
        />
      </el-form-item>
      <el-form-item label="卖家ID">
        <el-input
          v-model="queryParams.seller_id"
          placeholder="请输入卖家ID"
          clearable
          style="width: 200px"
        />
      </el-form-item>
      <el-form-item label="商品ID">
        <el-input
          v-model="queryParams.item_id"
          placeholder="请输入商品ID"
          clearable
          style="width: 200px"
        />
      </el-form-item>
      <el-form-item label="客户端">
        <el-select
          v-model="queryParams.client_id"
          placeholder="请选择客户端"
          clearable
          style="width: 200px"
        >
          <el-option label="所有客户端" value="" />
          <el-option
            v-for="client in clientOptions"
            :key="client.client_id"
            :label="client.display"
            :value="client.client_id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="消息类型">
        <el-select
          v-model="queryParams.message_type"
          placeholder="全部"
          clearable
          style="width: 150px"
        >
          <el-option label="文本" value="text" />
          <el-option label="图片" value="image" />
          <el-option label="语音" value="voice" />
          <el-option label="视频" value="video" />
          <el-option label="系统" value="system" />
          <el-option label="其它" value="other" />
        </el-select>
      </el-form-item>
      <el-form-item label="方向">
        <el-select
          v-model="queryParams.direction"
          placeholder="全部"
          clearable
          style="width: 150px"
        >
          <el-option label="收到" value="recv" />
          <el-option label="发送" value="send" />
        </el-select>
      </el-form-item>
      <el-form-item label="时间范围">
        <el-date-picker
          v-model="dateRange"
          type="datetimerange"
          range-separator="-"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          style="width: 360px"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="handleReset">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 工具栏 -->
    <el-row :gutter="10" class="mb-4">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="Refresh" @click="loadMessageList">刷新</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
      </el-col>
    </el-row>

    <!-- 消息列表 -->
    <el-table
      :data="messageList"
      border
      v-loading="loading"
      height="620"
    >
      <el-table-column label="时间" width="180" align="center">
        <template #default="{ row }">
          {{ formatDateTime(row.message_time) }}
        </template>
      </el-table-column>
      <el-table-column label="卖家" min-width="160">
        <template #default="{ row }">
          <div class="seller-info">
            <div class="seller-name">{{ row.seller_name || '-' }}</div>
            <div class="seller-id">ID: {{ row.seller_id }}</div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="商品" min-width="180">
        <template #default="{ row }">
          <div class="item-info">
            <div class="item-title" v-if="row.item_title">{{ row.item_title }}</div>
            <div class="item-id" v-if="row.item_id">ID: {{ row.item_id }}</div>
            <span v-if="!row.item_title && !row.item_id">-</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="类型" width="120" align="center">
        <template #default="{ row }">
          <el-tag :type="getMessageTypeTag(row.message_type)" size="small">
            {{ getMessageTypeLabel(row.message_type) }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="方向" width="100" align="center">
        <template #default="{ row }">
          <el-tag :type="row.direction === 'send' ? 'success' : 'info'" size="small">
            {{ row.direction === 'send' ? '我 → 卖家' : '卖家 → 我' }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="消息内容" min-width="240">
        <template #default="{ row }">
          <!-- 文本消息 -->
          <div v-if="row.message_type === 'text'" class="message-text">{{ row.message_content }}</div>
          
          <!-- 图片消息 -->
          <div v-else-if="row.message_type === 'image'" class="image-message">
            <el-image
              v-if="row.image_url"
              :src="row.image_url"
              :preview-src-list="[row.image_url]"
              fit="cover"
              style="width: 80px; height: 80px; cursor: pointer; border-radius: 4px;"
              :hide-on-click-modal="true"
              :z-index="3000"
            >
              <template #error>
                <div class="image-error">[图片加载失败]</div>
              </template>
            </el-image>
            <div v-else class="no-image-data">
              <el-icon><Picture /></el-icon>
              <span>[图片]</span>
            </div>
          </div>
          
          <!-- 语音消息 -->
          <div v-else-if="row.message_type === 'voice' && row.voice_url" class="message-voice">
            <!-- 隐藏的audio元素 -->
            <audio
              :data-message-id="row.id || row.message_id"
              :data-voice-url="row.voice_url"
              @error="handleVoiceError"
              @ended="handleVoiceEnded"
              style="display: none"
            />
            
            <!-- 语音播放器UI -->
            <div class="voice-player" @click="handleVoicePlay(row)">
              <el-icon class="voice-icon" :class="{ playing: isVoicePlaying(row) }">
                <component :is="isVoicePlaying(row) ? VideoPause : VideoPlay" />
              </el-icon>
              <div class="voice-wave">
                <span v-for="i in 4" :key="i" class="wave-bar" :class="{ playing: isVoicePlaying(row) }"></span>
              </div>
              <span class="voice-duration">{{ row.voice_duration || 0 }}''</span>
            </div>
          </div>
          
          <!-- 视频消息 -->
          <div v-else-if="row.message_type === 'video' && row.video_url" class="message-video">
            <el-icon><component :is="VideoCamera" /></el-icon>
            <span>视频消息</span>
            <video :src="row.video_url" :poster="row.video_cover" controls style="width: 160px; height: 90px; margin-left: 8px; border-radius: 4px;" />
          </div>
          
          <!-- system消息 -->
          <div v-else-if="row.message_type === 'system'" class="message-system">
            <el-icon><component :is="Bell" /></el-icon>
            <span>{{ row.message_content || '[系统消息]' }}</span>
          </div>
          
          <!-- 其他消息 -->
          <span v-else class="message-text">{{ row.message_content || '-' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="客户端" width="160" align="center">
        <template #default="{ row }">
          <div class="client-info">
            <div>{{ row.client_name || '-' }}</div>
            <div class="client-id">{{ row.client_id }}</div>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="160" fixed="right" align="center">
        <template #default="{ row }">
          <el-button
            link
            type="primary"
            icon="View"
            @click="handleViewDetail(row)"
          >详情</el-button>
          <el-button
            link
            type="danger"
            icon="Delete"
            @click="handleDelete(row)"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <el-pagination
      class="mt-4"
      v-model:current-page="queryParams.pageNum"
      v-model:page-size="queryParams.pageSize"
      :page-sizes="[10, 20, 50, 100]"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handlePageChange"
      @current-change="handlePageChange"
    />

    <!-- 消息详情 -->
    <el-dialog
      v-model="detailDialogVisible"
      title="消息详情"
      width="580px"
      :close-on-click-modal="false"
    >
      <template v-if="currentMessage">
        <el-descriptions :column="1" border size="small">
          <el-descriptions-item label="时间">{{ formatDateTime(currentMessage.message_time) }}</el-descriptions-item>
          <el-descriptions-item label="卖家昵称">{{ currentMessage.seller_name || '-' }}</el-descriptions-item>
          <el-descriptions-item label="卖家ID">{{ currentMessage.seller_id || '-' }}</el-descriptions-item>
          <el-descriptions-item label="商品标题">{{ currentMessage.item_title || '-' }}</el-descriptions-item>
          <el-descriptions-item label="商品ID">{{ currentMessage.item_id || '-' }}</el-descriptions-item>
          <el-descriptions-item label="客户端">{{ currentMessage.client_name || currentMessage.client_id || '-' }}</el-descriptions-item>
          <el-descriptions-item label="消息类型">
            <el-tag :type="getMessageTypeTag(currentMessage.message_type)" size="small">
              {{ getMessageTypeLabel(currentMessage.message_type) }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="消息方向">
            <el-tag :type="currentMessage.direction === 'send' ? 'success' : 'info'" size="small">
              {{ currentMessage.direction === 'send' ? '发送' : '收到' }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="消息内容">
            <!-- 文本消息 -->
            <div v-if="currentMessage.message_type === 'text'" class="message-detail-text">{{ currentMessage.message_content }}</div>
            
            <!-- 图片消息 -->
            <div v-else-if="currentMessage.message_type === 'image'">
              <el-image
                v-if="currentMessage.image_url"
                :src="currentMessage.image_url"
                :preview-src-list="[currentMessage.image_url]"
                fit="contain"
                style="max-width: 100%; max-height: 360px; cursor: pointer;"
                :hide-on-click-modal="true"
                :z-index="3000"
              >
                <template #error>
                  <div class="image-error">[图片加载失败]</div>
                </template>
              </el-image>
              <div v-else class="no-image-data">
                <el-icon><component :is="Picture" /></el-icon>
                <span>图片消息（无图片数据）</span>
              </div>
            </div>
            
            <!-- 语音消息 -->
            <div v-else-if="currentMessage.message_type === 'voice' && (currentMessage.voice_url || currentMessage.message_content)" class="message-voice-detail">
              <div class="voice-info">
                <el-icon><component :is="Headset" /></el-icon>
                <span>语音消息{{ currentMessage.voice_duration ? ' ' + currentMessage.voice_duration + '秒' : '' }}</span>
              </div>
              <audio :src="currentMessage.voice_url || currentMessage.message_content" controls preload="metadata" style="width: 100%; margin-top: 8px;" />
            </div>
            
            <!-- 视频消息 -->
            <div v-else-if="currentMessage.message_type === 'video' && currentMessage.video_url" class="message-video-detail">
              <div class="video-info">
                <el-icon><component :is="VideoCamera" /></el-icon>
                <span>视频消息</span>
              </div>
              <video :src="currentMessage.video_url" :poster="currentMessage.video_cover" controls style="max-width: 100%; margin-top: 8px; border-radius: 4px;" />
            </div>
            
            <!-- system消息 -->
            <div v-else-if="currentMessage.message_type === 'system'" class="message-system-detail">
              <el-icon><component :is="Bell" /></el-icon>
              <span>{{ currentMessage.message_content || '[系统消息]' }}</span>
            </div>
            
            <!-- 其他消息 -->
            <div v-else>{{ currentMessage.message_content || '-' }}</div>
          </el-descriptions-item>
        </el-descriptions>
        
        <!-- 调试信息（开发模式）：可选展开查看原始数据 -->
        <el-collapse v-if="false" style="margin-top: 16px;">
          <el-collapse-item title="调试信息（扩展数据）" name="1">
            <div class="json-box" v-if="parsedMessageExtra">
              <pre>{{ parsedMessageExtra }}</pre>
            </div>
            <span v-else>-</span>
          </el-collapse-item>
        </el-collapse>
      </template>
      <template #footer>
        <el-button @click="detailDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { computed, onMounted, reactive, ref, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Headset, VideoCamera, Bell, Picture, VideoPlay, VideoPause } from '@element-plus/icons-vue'
import { getSellerMessageList, deleteSellerMessage, getAgentClientList } from '@/api/agent'

const loading = ref(false)
const total = ref(0)
const messageList = ref([])
const dateRange = ref([])
const clientOptions = ref([])

const queryParams = reactive({
  seller_name: '',
  seller_id: '',
  item_id: '',
  client_id: '',
  message_type: '',
  direction: '',
  pageNum: 1,
  pageSize: 20
})

const detailDialogVisible = ref(false)
const currentMessage = ref(null)

// ===== 语音播放状态管理 =====
const playingVoiceMessageId = ref(null)
const amrPlayerInstances = ref(new Map())

const parsedMessageExtra = computed(() => {
  if (!currentMessage.value || !currentMessage.value.message_extra) return null
  try {
    const data = typeof currentMessage.value.message_extra === 'string'
      ? JSON.parse(currentMessage.value.message_extra)
      : currentMessage.value.message_extra
    return JSON.stringify(data, null, 2)
  } catch (error) {
    return currentMessage.value.message_extra
  }
})

async function loadMessageList() {
  loading.value = true
  try {
    const params = {
      page_num: queryParams.pageNum,
      page_size: queryParams.pageSize
    }

    if (queryParams.seller_name) params.seller_name = queryParams.seller_name
    if (queryParams.seller_id) params.seller_id = queryParams.seller_id
    if (queryParams.item_id) params.item_id = queryParams.item_id
    if (queryParams.client_id) params.client_id = queryParams.client_id
    if (queryParams.message_type) params.message_type = queryParams.message_type
    if (queryParams.direction) params.direction = queryParams.direction

    if (dateRange.value && dateRange.value.length === 2) {
      params.start_time = toISOString(dateRange.value[0])
      params.end_time = toISOString(dateRange.value[1])
    }

    const { data } = await getSellerMessageList(params)
    messageList.value = data?.rows || []
    total.value = data?.total || 0
  } catch (error) {
    console.error('[SellerMessages] 加载失败', error)
    ElMessage.error(`加载对话记录失败：${error.message || '未知错误'}`)
    messageList.value = []
    total.value = 0
  } finally {
    loading.value = false
  }
}

function handleQuery() {
  queryParams.pageNum = 1
  loadMessageList()
}

function handleReset() {
  queryParams.seller_name = ''
  queryParams.seller_id = ''
  queryParams.item_id = ''
  queryParams.client_id = ''
  queryParams.message_type = ''
  queryParams.direction = ''
  dateRange.value = []
  queryParams.pageNum = 1
  loadMessageList()
}

function handlePageChange() {
  loadMessageList()
}

function handleExport() {
  ElMessage.info('导出功能开发中，敬请期待~')
}

function handleViewDetail(message) {
  currentMessage.value = message
  detailDialogVisible.value = true
}

async function handleDelete(row) {
  if (!row || !row.id) return
  try {
    await ElMessageBox.confirm(
      `确定要删除与卖家 "${row.seller_name || row.seller_id}" 的消息吗？`,
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    await deleteSellerMessage(row.id)
    ElMessage.success('删除成功')
    loadMessageList()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('[SellerMessages] 删除失败', error)
      ElMessage.error(`删除失败：${error.message || '未知错误'}`)
    }
  }
}

function getMessageTypeTag(type) {
  const map = {
    text: 'info',
    image: 'success',
    voice: 'warning',
    video: 'danger',
    system: '',
    other: 'info'
  }
  return map[type] || 'info'
}

function getMessageTypeLabel(type) {
  const map = {
    text: '文本',
    image: '图片',
    voice: '语音',
    video: '视频',
    system: '系统',
    other: '其它'
  }
  return map[type] || type || '-'
}

function formatDateTime(value) {
  if (!value) return '-'
  const date = value instanceof Date ? value : new Date(value)
  if (Number.isNaN(date.getTime())) return '-'
  return date.toLocaleString()
}

function toISOString(value) {
  if (!value) return undefined
  const date = value instanceof Date ? value : new Date(value)
  if (Number.isNaN(date.getTime())) return undefined
  return date.toISOString()
}

// ===== 语音播放功能 =====

// 判断是否正在播放
function isVoicePlaying(row) {
  const msgId = row.id || row.message_id
  return playingVoiceMessageId.value === msgId
}

// AMR格式检测
function detectAMRFormat(arrayBuffer) {
  if (!arrayBuffer || arrayBuffer.byteLength < 6) {
    return false
  }
  
  const view = new Uint8Array(arrayBuffer, 0, 6)
  // AMR格式文件头是 "#!AMR" (0x23 0x21 0x41 0x4D 0x52)
  if (view[0] === 0x23 && view[1] === 0x21 && 
      view[2] === 0x41 && view[3] === 0x4D && view[4] === 0x52) {
    return true
  }
  
  return false
}

// 使用BenzAMRRecorder播放AMR音频
async function playAMRAudio(arrayBuffer, audioElement, messageId) {
  return new Promise((resolve, reject) => {
    if (typeof window === 'undefined' || !window.BenzAMRRecorder) {
      console.error('[SellerMessages] ❌ BenzAMRRecorder未加载')
      reject(new Error('AMR解码器未加载'))
      return
    }
    
    console.log('[SellerMessages] 🎵 开始播放AMR音频...')
    playingVoiceMessageId.value = messageId
    
    try {
      const blob = new Blob([arrayBuffer], { type: 'audio/amr' })
      const blobUrl = URL.createObjectURL(blob)
      const amr = new window.BenzAMRRecorder()
      
      amrPlayerInstances.value.set(messageId, amr)
      
      amr.initWithUrl(blobUrl).then(() => {
        console.log('[SellerMessages] ✅ AMR初始化成功，开始播放')
        
        const cleanup = () => {
          URL.revokeObjectURL(blobUrl)
          amrPlayerInstances.value.delete(messageId)
          if (playingVoiceMessageId.value === messageId) {
            playingVoiceMessageId.value = null
          }
        }
        
        if (typeof amr.onEnded === 'function') {
          amr.onEnded(() => {
            console.log('[SellerMessages] ✅ AMR播放结束')
            cleanup()
            resolve()
          })
        }
        
        amr.play()
      }).catch((err) => {
        console.error('[SellerMessages] ❌ AMR初始化失败:', err)
        playingVoiceMessageId.value = null
        amrPlayerInstances.value.delete(messageId)
        reject(err)
      })
    } catch (err) {
      console.error('[SellerMessages] ❌ AMR播放失败:', err)
      playingVoiceMessageId.value = null
      reject(err)
    }
  })
}

// 语音播放主函数
async function handleVoicePlay(row) {
  const messageId = row.id || row.message_id
  const voiceUrl = row.voice_url
  
  if (!voiceUrl) {
    ElMessage.error('语音URL缺失')
    return
  }
  
  // 如果正在播放当前消息，则暂停
  if (playingVoiceMessageId.value === messageId) {
    const amrPlayer = amrPlayerInstances.value.get(messageId)
    if (amrPlayer) {
      try {
        if (typeof amrPlayer.stop === 'function') {
          amrPlayer.stop()
        } else if (typeof amrPlayer.pause === 'function') {
          amrPlayer.pause()
        }
        amrPlayerInstances.value.delete(messageId)
      } catch (err) {
        console.warn('[SellerMessages] 停止AMR播放失败:', err)
      }
    } else {
      const audioElement = document.querySelector(`audio[data-message-id="${messageId}"]`)
      if (audioElement) {
        audioElement.pause()
      }
    }
    playingVoiceMessageId.value = null
    return
  }
  
  // 暂停其他正在播放的语音
  if (playingVoiceMessageId.value) {
    const currentMessageId = playingVoiceMessageId.value
    const amrPlayer = amrPlayerInstances.value.get(currentMessageId)
    
    if (amrPlayer) {
      try {
        if (typeof amrPlayer.stop === 'function') {
          amrPlayer.stop()
        } else if (typeof amrPlayer.pause === 'function') {
          amrPlayer.pause()
        }
        amrPlayerInstances.value.delete(currentMessageId)
      } catch (err) {
        console.warn('[SellerMessages] 停止其他AMR播放失败:', err)
      }
    } else {
      const currentAudio = document.querySelector(`audio[data-message-id="${currentMessageId}"]`)
      if (currentAudio) {
        currentAudio.pause()
        currentAudio.currentTime = 0
      }
    }
  }
  
  // AMR格式检测和播放
  try {
    const response = await fetch(voiceUrl, {
      method: 'GET',
      mode: 'cors',
      credentials: 'omit',
      headers: {
        'Range': 'bytes=0-5'
      }
    })
    
    if (response.ok || response.status === 206) {
      const buffer = await response.arrayBuffer()
      const isAMR = detectAMRFormat(buffer)
      
      if (isAMR) {
        console.log('[SellerMessages] 检测到AMR格式，使用AMR播放器')
        const fullResponse = await fetch(voiceUrl, {
          method: 'GET',
          mode: 'cors',
          credentials: 'omit'
        })
        
        if (fullResponse.ok || fullResponse.status === 206) {
          const fullBuffer = await fullResponse.arrayBuffer()
          const audioElement = document.querySelector(`audio[data-message-id="${messageId}"]`)
          await playAMRAudio(fullBuffer, audioElement, messageId)
          return
        }
      }
    }
  } catch (err) {
    console.warn('[SellerMessages] AMR格式检测失败，使用普通播放:', err)
  }
  
  // 使用普通audio元素播放
  nextTick(async () => {
    const audioElement = document.querySelector(`audio[data-message-id="${messageId}"]`)
    
    if (!audioElement) {
      console.warn('[SellerMessages] 未找到audio元素')
      return
    }
    
    if (audioElement.src !== voiceUrl) {
      audioElement.src = voiceUrl
      audioElement.load()
    }
    
    playingVoiceMessageId.value = messageId
    
    if (audioElement.readyState === 0) {
      try {
        await Promise.race([
          new Promise((resolve) => {
            if (audioElement.readyState >= 1) {
              resolve()
              return
            }
            
            const checkInterval = setInterval(() => {
              if (audioElement.readyState >= 1) {
                clearInterval(checkInterval)
                resolve()
              }
            }, 100)
            
            audioElement.addEventListener('canplay', () => {
              clearInterval(checkInterval)
              resolve()
            }, { once: true })
          }),
          new Promise((resolve) => setTimeout(resolve, 2000))
        ])
      } catch (err) {
        console.warn('[SellerMessages] 等待音频就绪超时:', err)
      }
    }
    
    try {
      await audioElement.play()
      console.log('[SellerMessages] ✅ 普通音频播放成功')
    } catch (err) {
      console.error('[SellerMessages] 播放失败:', err)
      ElMessage.error(`播放失败: ${err.message}`)
      playingVoiceMessageId.value = null
    }
  })
}

// 语音播放结束
function handleVoiceEnded() {
  console.log('[SellerMessages] 播放结束')
  playingVoiceMessageId.value = null
}

// 语音播放错误
function handleVoiceError(event) {
  const audioElement = event.target
  const messageId = audioElement.getAttribute('data-message-id')
  const voiceUrl = audioElement.getAttribute('data-voice-url')
  
  console.error('[SellerMessages] 播放错误:', {
    messageId,
    voiceUrl,
    error: event
  })
  
  ElMessage.error('语音加载失败')
  playingVoiceMessageId.value = null
}

async function loadClientOptions() {
  try {
    const { data } = await getAgentClientList({ pageNum: 1, pageSize: 500 })
    const rows = data?.rows || []
    clientOptions.value = rows.map(row => ({
      client_id: row.client_id,
      display: row.client_name || row.hostname || row.client_id
    }))
  } catch (error) {
    console.warn('[SellerMessages] 加载客户端列表失败', error)
  }
}

onMounted(() => {
  loadClientOptions()
  loadMessageList()
})
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.mb-4 {
  margin-bottom: 16px;
}

.mt-4 {
  margin-top: 16px;
}

.seller-info .seller-name {
  font-weight: 600;
}

.seller-info .seller-id {
  font-size: 12px;
  color: #909399;
}

.item-info .item-title {
  font-weight: 500;
}

.item-info .item-id {
  font-size: 12px;
  color: #909399;
}

.message-text {
  max-width: 100%;
  word-break: break-word;
}

.message-detail-text {
  white-space: pre-wrap;
  word-break: break-word;
}

.json-box {
  background: #1f2933;
  color: #f8fafc;
  padding: 12px;
  border-radius: 4px;
  max-height: 260px;
  overflow: auto;
}

.client-info {
  font-size: 13px;
}

.client-id {
  color: #909399;
  font-size: 12px;
}

.message-voice {
  display: inline-block;
}

.voice-player {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 20px;
  cursor: pointer;
  user-select: none;
  transition: all 0.3s ease;
  min-width: 120px;
}

.voice-player:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}

.voice-player:active {
  transform: translateY(0);
}

.voice-icon {
  font-size: 20px;
  color: white;
  transition: transform 0.3s ease;
}

.voice-icon.playing {
  animation: pulse 1.5s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

.voice-wave {
  display: flex;
  align-items: center;
  gap: 3px;
  height: 20px;
}

.wave-bar {
  width: 3px;
  height: 8px;
  background: rgba(255, 255, 255, 0.6);
  border-radius: 2px;
  transition: all 0.3s ease;
}

.wave-bar.playing {
  animation: wave 1s ease-in-out infinite;
}

.wave-bar:nth-child(1).playing { animation-delay: 0s; }
.wave-bar:nth-child(2).playing { animation-delay: 0.2s; }
.wave-bar:nth-child(3).playing { animation-delay: 0.4s; }
.wave-bar:nth-child(4).playing { animation-delay: 0.6s; }

@keyframes wave {
  0%, 100% { height: 8px; background: rgba(255, 255, 255, 0.6); }
  50% { height: 20px; background: rgba(255, 255, 255, 1); }
}

.voice-duration {
  font-size: 12px;
  color: white;
  font-weight: 500;
}

.message-video,
.message-system {
  display: flex;
  align-items: center;
  gap: 6px;
}

.message-video .el-icon,
.message-system .el-icon {
  color: #409eff;
}

.message-system {
  color: #909399;
  font-style: italic;
}

.image-error {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80px;
  height: 80px;
  background: #f5f7fa;
  color: #909399;
  font-size: 12px;
  border-radius: 4px;
}

.no-image-data {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: #f5f7fa;
  color: #909399;
  border-radius: 4px;
  font-size: 13px;
}

.no-image-data .el-icon {
  font-size: 18px;
}

.message-voice-detail,
.message-video-detail,
.message-system-detail {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.voice-info,
.video-info {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #409eff;
}

.message-system-detail {
  display: flex;
  align-items: center;
  gap: 6px;
  color: #909399;
  font-style: italic;
}

/* 修复图片预览弹窗z-index */
:deep(.el-image-viewer__wrapper) {
  z-index: 3000 !important;
}

/* 修复图片加载错误显示 */
:deep(.el-image__error) {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f5f7fa;
  color: #909399;
  font-size: 12px;
}
</style>
